using IQIGame.Onigao.Framework;
using IQIGame.Onigao.Game;
using UnityEngine;

namespace IQIGame.Onigao.GamePlay
{
    public abstract class EntityAudioComponent : TReusableEvtComponent
    {
        public override uint MaxStore => 50;
        private CriAudioSource _source;

        public override void OnComponentEvent<T>(TComponentEvent eventType, T arg)
        {
            switch (eventType)
            {
                case TComponentEvent.OnEntityObjectLoaded:
                    OnPlayAudio();
                    break;
                case TComponentEvent.OnEntityObjectHided:
                    OnDestroyAudio();
                    break;
                case TComponentEvent.OnEntityObjectVisible:
                    OnPlayAudio();
                    break;
                case TComponentEvent.OnEntityObjectInvisible:
                    OnDestroyAudio();
                    break;
            }
        }

        protected abstract void OnPlayAudio();
        protected abstract GameObject GetGameObject();

        protected void OnDestroyAudio()
        {
            StopAudio(true);
        }

        public void PlayAudio(int audioCid)
        {
            StopAudio(false);
            if (audioCid == 0)
            {
                return;
            }
            var go = GetGameObject();
            if (go == null)
            {
                LogGame.LogError("播放音效失败，找不到GameObject，该组件只能适用于有模型的实体。");
                return;
            }
            if (_source == null)
            {
                _source = ManagerCenter.Audio.AddAudioSource(GetGameObject());
            }
            if (!AudioManager.TableVisitorAudio(audioCid, out var cueName, out var sheetName, out var audioSourceType, out var selector, out var label))
            {
                LogGame.LogError("找不到Audio.id = " + audioCid);
                return;
            }
            if (audioSourceType != AudioSourceType.Entity)
            {
                LogGame.LogError($"Audio.Type 错误。应该 == 5(Entity)，实际 == {(int)audioSourceType}");
            }
            _source.PlayAudioWithLabel(cueName, sheetName, AudioSourceType.Entity, selector, label);
        }

        protected void StopAudio(bool removeSource = false)
        {
            if (_source == null)
            {
                return;
            }
            _source.StopSource();
            if (removeSource)
            {
                _source.Dispose();
                _source = null;
            }
        }

        public override void Free()
        {
            StopAudio(true);
            base.Free();
        }

        public override void OnPoolReset()
        {
            _source = null;
        }
    }
}
